#pragma once

MAPPING_VALUE(DriveModeSelection, sdb::DrvModReqType2, sdb::DrvModReqType2::DrvModReqType1_Undefd)
    MAPPING_ITEM(DriveModeSelection::DRIVE_MODE_SELECTION_UNKNOWN, sdb::DrvModReqType2::DrvModReqType1_Undefd)
    MAPPING_ITEM(DriveModeSelection::DRIVE_MODE_SELECTION_ECO, sdb::DrvModReqType2::DrvModReqType1_ECO)
    MAPPING_ITEM(DriveModeSelection::DRIVE_MODE_SELECTION_NORMAL, sdb::DrvModReqType2::DrvModReqType1_Comfort_Normal)
    MAPPING_ITEM(DriveModeSelection::DRIVE_MODE_SELECTION_DYNAMIC, sdb::DrvModReqType2::DrvModReqType1_Dynamic_Sport)
    MAPPING_ITEM(DriveModeSelection::DRIVE_MODE_SPORT_PLUS, sdb::DrvModReqType2::DrvModReqType1_Race)
    MAPPING_ITEM(DriveModeSelection::DRIVE_MODE_SELECTION_OFFROAD, sdb::DrvModReqType2::DrvModReqType1_Offroad_CrossTerrain)
MAPPING_END

MAPPING_VALUE(sdb::DrvModReqType2, DriveModeSelection, DriveModeSelection::DRIVE_MODE_SELECTION_UNKNOWN)
    MAPPING_ITEM(sdb::DrvModReqType2::DrvModReqType1_Undefd, DriveModeSelection::DRIVE_MODE_SELECTION_UNKNOWN)
    MAPPING_ITEM(sdb::DrvModReqType2::DrvModReqType1_ECO, DriveModeSelection::DRIVE_MODE_SELECTION_ECO)
    MAPPING_ITEM(sdb::DrvModReqType2::DrvModReqType1_Comfort_Normal, DriveModeSelection::DRIVE_MODE_SELECTION_NORMAL)
    MAPPING_ITEM(sdb::DrvModReqType2::DrvModReqType1_Dynamic_Sport, DriveModeSelection::DRIVE_MODE_SELECTION_DYNAMIC)
    MAPPING_ITEM(sdb::DrvModReqType2::DrvModReqType1_Race, DriveModeSelection::DRIVE_MODE_SPORT_PLUS)
    MAPPING_ITEM(sdb::DrvModReqType2::DrvModReqType1_Offroad_CrossTerrain, DriveModeSelection::DRIVE_MODE_SELECTION_OFFROAD)
MAPPING_END

namespace ecarx::vhal::core::property::DriveModeUtil {
    inline DriveModeSelection getDefaultDriveMode() {
        if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_01, sdb::CarConfig13::_02,
            sdb::CarConfig13::_04, sdb::CarConfig13::_80)) {
            return DriveModeSelection::DRIVE_MODE_SELECTION_NORMAL;
        }
        return DriveModeSelection::DRIVE_MODE_SELECTION_UNKNOWN;
    }

    inline bool isPersist() {
        VHALOG.d("DriveModeUtil isPersist cc13: %d, cc220: %d", SIGNAL.getcarconfig13(), SIGNAL.getcarconfig220());
        return SIGNAL.carConfigIs(SignalRX::carconfig220, sdb::CarConfig220::_0A) &&
                    SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04);
    }

    inline PropertyStatus getDriveModeSelectStatus() {
        if (SIGNAL.carConfigIs(SignalRX::carconfig13, sdb::CarConfig13::_04)) {
            if (SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm,
                                sdb::CarModSts1::CarModCrash,
                                sdb::CarModSts1::CarModDyno) &&
                SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModActv, sdb::UsgModSts1::UsgModDrvg,
                                sdb::UsgModSts1::UsgModCnvinc)) {
                return PropertyStatus::Active;
            }
        } else {
            if (SIGNAL.carModeIs(sdb::CarModSts1::CarModNorm,
                                sdb::CarModSts1::CarModCrash,
                                sdb::CarModSts1::CarModDyno) &&
                SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModActv, sdb::UsgModSts1::UsgModDrvg)) {
                return PropertyStatus::Active;
            }
        }
        return PropertyStatus::NotActive;
    }

    inline sdb::SteerErrReq3 getFwkSteerErrReq() {
        VHALOG.d("DriveModeUtil getFwkSteerErrReq usgmod: %d, steerErrReqTimeout: %d", SIGNAL.getVehModMngtGlbSafe1UsgModSts(), SIGNAL.getSteerErrReqTimeout());
        if (!SIGNAL.usgModeIs(sdb::UsgModSts1::UsgModActv, sdb::UsgModSts1::UsgModDrvg) ||
            SIGNAL.getSteerErrReqTimeout() == sdb::Timeout::Timeout) {
            return sdb::SteerErrReq3::NoReq;
        }
        return SIGNAL.getSteerErrReq();
    }

}

using namespace ::ecarx::vhal::core::property::DriveModeUtil;